<template>
  <view class="sv-exam">
    <template v-if="showExam">
      <!-- 答题区域 -->
      <exam-paper v-model:paper="curPaper"></exam-paper>
      <!-- 答题卡区域 -->
      <exam-card v-if="showCard" v-model:paper="curPaper"></exam-card>
    </template>
    <view class="exam-empty-loading" v-else>
      <view class="exam-loading-cube"></view>
      <view class="exam-loading-text">加载中...</view>
    </view>
    <!-- #ifdef MP-WEIXIN -->
    <!-- 微信小程序使用page-container方式拦截返回 -->
    <page-container :show="showPageContainer" :duration="false" :overlay="false"
      @beforeleave="beforeleave"></page-container>
    <!-- #endif -->
  </view>
</template>

<script setup>
import { computed, onMounted, onUnmounted, provide, ref, watch } from 'vue'
import ExamCard from './exam-card.vue'
import ExamPaper from './exam-paper.vue'
import config from './config.js'
import packageConfig from '../../package.json'

const props = defineProps({
  /**
   * 三种答题模式
   * recite 背题模式 题库中顺序出题，带有答案，只需看题背答案，无需手动写题，可继续背题
   * practice 刷题模式 题库中顺序出题，答题完自动批改对错并给出答案，可继续或重新答题
   * exam 模拟考试 题库中随机抽取指定数量道题并打乱顺序，提交后自动批改，退出考试时弹出提示，时间到自动交卷
   */
  type: {
    type: String,
    default: ''
  },
  lib: {
    type: String,
    default: ''
  },
  data: {
    type: Array,
    default: () => []
  },
  favs: {
    type: Array,
    default: () => []
  },
  // 是否显示答题卡
  showCard: {
    type: Boolean,
    default: true
  },
})

// 根据是否显示答题卡，动态改变试题内容盒子高度
const cardHeaderHeight = ref(props.showCard ? '50px' : '0px')

const emits = defineEmits(['changePaper', 'quit'])

const examType = ref(props.type)
const examData = ref(props.data)
const examFavs = ref(props.favs)
provide('sv-exam-type', examType)
provide('sv-exam-data', examData)
provide('sv-exam-favs', examFavs)

const paperIndex = computed({
  set(newIndex) {
    if (!props.lib) return
    const storage = uni.getStorageSync('sv-exam')
    switch (props.type) {
      case config.examTypeDict[0]:
        storage[props.lib] = Object.assign({ ...storage[props.lib] }, { reciteIndex: newIndex })
        break
      case config.examTypeDict[1]:
        storage[props.lib] = Object.assign({ ...storage[props.lib] }, { practiceIndex: newIndex })
        break
    }
    uni.setStorageSync('sv-exam', storage)
  },
  get() {
    let index = 0
    const storage = uni.getStorageSync('sv-exam')
    try {
      if (!props.lib) throw new Error('lib is undefined')
      switch (props.type) {
        case config.examTypeDict[0]:
          index = storage[props.lib].reciteIndex || 0
          break
        case config.examTypeDict[1]:
          index = storage[props.lib].practiceIndex || 0
          break
        case config.examTypeDict[2]:
          index = 0
          break
      }
    } catch (e) {
      // 当缓存中缺失部分参数时，默认归零
      index = 0
    }
    return index
  }
})

// 初始默认题目
const curPaper = ref({ data: examData.value[paperIndex.value], index: paperIndex.value })

// 监听考试类型改变
watch(() => props.type, (newType) => {
  examType.value = newType
  const storage = uni.getStorageSync('sv-exam')
  uni.setStorageSync('sv-exam', Object.assign({ ...storage }, { examType: newType }))
}, { immediate: true })

// 监听题目加载完成
const showExam = ref(false)
watch(() => props.data, (newData) => {
  examData.value = newData
  curPaper.value = { data: newData[paperIndex.value], index: paperIndex.value }
  showExam.value = true
}, { immediate: true })

// 监听收藏
watch(() => props.favs, (newFavs) => {
  examFavs.value = newFavs
})

// 监听题目切换
watch(() => curPaper.value.index, (newIndex) => {
  paperIndex.value = newIndex
  emits('changePaper', curPaper.value)
})

// 返回拦截
// #ifndef MP-WEIXIN
let quitFlag = true
uni.addInterceptor('navigateBack', {
  invoke() {
    if (props.type == config.examTypeDict[2] && quitFlag) {
      uni.showModal({
        title: '系统提示',
        content: config.quitText,
        showCancel: true,
        success: ({ confirm }) => {
          if (confirm) {
            quitFlag = false
            uni.navigateBack({ delta: 1 })
            return false
          }
        }
      })
      return false
    }
  },
  complete() {
    // 删除拦截器
    uni.removeInterceptor('navigateBack')
  }
})
// #endif

// #ifdef MP-WEIXIN
const showPageContainer = ref(false)
onMounted(() => {
  showPageContainer.value = props.type == config.examTypeDict[2] ? true : false
})

function beforeleave() {
  showPageContainer.value = false // 必须先隐藏page-container
  if (props.type == config.examTypeDict[2]) {
    uni.showModal({
      title: '系统提示',
      content: config.quitText,
      showCancel: true,
      success: ({ confirm }) => {
        if (confirm) {
          uni.navigateBack({ delta: 1 })
        } else {
          showPageContainer.value = true
        }
      }
    })
  }
}
// #endif

onUnmounted(() => {
  emits('quit', examData.value)
})

// 水印
/* 版权样式 */
const styleTitle1 = `font-size:18px;font-weight:700;color:#1a5fff;`
const styleTitle2 = `font-style:oblique;font-size:14px;color:#fb7299;`
const styleContent = `color: #3482ff;`
/* 版权信息 */
const title1 = '📝 sv-exam 💯'
const title2 = 'by 夏夜追凉丶(Sonve)'
const content = `
版 本 号：${packageConfig.version}
版权声明：
1. sv-exam版权完全属于 "夏夜追凉丶(Sonve)"
2. 任何个人和机构在遵守下列条件的前提下永久授权使用:
	1) 保留此版权信息在控制台输出
	2) 如需商用，还请联系作者
作者将保留对此版权信息的最终解释权
🏠 地址: https://ext.dcloud.net.cn/plugin?id=16161
📞 微信: s1051399604
`
console.log(`%c${title1} %c${title2} %c${content}`, styleTitle1, styleTitle2, styleContent)
</script>

<style lang="scss">
.sv-exam {
  --bg-color: #ffffff; // 主要背景
  --sub-bg-color: rgba(0, 216, 134, 0.1); // 次要背景
  --border-color: #e6e6e6; // 边框色
  --border-highlight-color: #01beff; // 边框高亮色
  --primary-color: #01beff; // 行为配色
  --success-color: #00d886; // 行为配色
  --warning-color: #ff0808; // 行为配色
  --error-color: #ff444f; // 行为配色
  --info-color: rgba(0, 216, 134, 0.1); // 行为配色
  --card-height: 50vh; // 答题卡高度

  --card-header-height: #{v-bind(cardHeaderHeight)}; // 答题卡头部高度
  // 单元单位建议非必要勿修改，使用rpx会存在一些样式问题，这里统一使用px
  // --paper-unit-12: 24rpx; // 单元尺寸 12px
  // --paper-unit-16: 32rpx; // 单元尺寸 16px
  --paper-unit-12: 12px; // 单元尺寸 12px
  --paper-unit-16: 16px; // 单元尺寸 16px

  width: 100%;
  height: 100%;
  box-sizing: border-box;

  .exam-empty-loading {
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;

    .exam-loading-text {
      font-size: var(--paper-unit-12);
      line-height: 2.4;
    }
  }
}

.primary-color {
  color: var(--primary-color);
}

.success-color {
  color: var(--success-color);
}

.warning-color {
  color: var(--warning-color);
}

.error-color {
  color: var(--error-color);
}

.info-color {
  color: var(--info-color);
}

// loading动画
.exam-loading-cube {
  --size: 10px;
  --color: white;
  width: 20px;
  height: 20px;
  position: relative;
}

.exam-loading-cube::after,
.exam-loading-cube::before {
  box-sizing: border-box;
  position: absolute;
  content: '';
  width: var(--size);
  height: var(--size);
  top: 50%;
  animation: exam-loading-cube-up 2.4s cubic-bezier(0, 0, 0.24, 1.21) infinite;
  left: 50%;
  background: var(--color);
  box-shadow: 0 0 calc(var(--size) / 3) rgba(0, 0, 0, 0.25);
}

.exam-loading-cube::after {
  background: var(--color);
  top: calc(50% - var(--size));
  left: calc(50% - var(--size));
  animation: exam-loading-cube-down 2.4s cubic-bezier(0, 0, 0.24, 1.21) infinite;
}

@keyframes exam-loading-cube-down {

  0%,
  100% {
    transform: none;
  }

  25% {
    transform: translateX(100%);
  }

  50% {
    transform: translateX(100%) translateY(100%);
  }

  75% {
    transform: translateY(100%);
  }
}

@keyframes exam-loading-cube-up {

  0%,
  100% {
    transform: none;
  }

  25% {
    transform: translateX(-100%);
  }

  50% {
    transform: translateX(-100%) translateY(-100%);
  }

  75% {
    transform: translateY(-100%);
  }
}
</style>